package net.jueb.sniff4j.extr.sendHandler;
import net.jueb.sniff4j.extr.base.AbstractRuntime;
import net.jueb.sniff4j.extr.build.filter.AbstractObjectFilter;
import net.jueb.sniff4j.socksCroe.SocksServerUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

/**
 * 代理服务器和客户端直接的数据处理handler
 * 将客户端的数据发送到目标主机
 * @author Administrator
 *
 */
public class SendToTargetHandler extends ChannelHandlerAdapter{
	protected static final InternalLogger log = InternalLoggerFactory.getInstance(SendToTargetHandler.class);
	private Channel proxyTargeChannel;
	private AbstractRuntime rt;
	public SendToTargetHandler(Channel proxyTargeChannel,AbstractRuntime rt) {
		this.proxyTargeChannel=proxyTargeChannel;
		this.rt=rt;
	}
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object request)throws Exception 
	{
		if(request==null)
		{
			return;
		}
		AbstractObjectFilter filter=rt.getSendToTargetFilter(ctx.channel(),proxyTargeChannel);
		Object obj=filter.getFiltResult(request);
		if(obj==null)
		{//如果重构的消息为null，则表示被丢弃,执行了shell
			return;
		}
		if(proxyTargeChannel.isActive())
		{
			proxyTargeChannel.writeAndFlush(obj);
			log.info(">>>>>>>>>>>>>>>>>>客户端发送数据完毕>>>>>>>>>>>>>>>>>>");
			
		}else
		{
			ReferenceCountUtil.release(obj);
			log.info("目标主机关闭连接!");
		}
	}
	

	 @Override
	 public void channelInactive(ChannelHandlerContext ctx) throws Exception {
	     if (proxyTargeChannel.isActive()) {
	         SocksServerUtils.closeOnFlush(proxyTargeChannel);
	     }
	 }
	 @Override
	 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
	     cause.printStackTrace();
	     ctx.close();
	 }
	 @Override
	public void close(ChannelHandlerContext ctx, ChannelPromise promise)
			throws Exception {
		//TODO //当代理服务器和客户端的通道被关闭时，删除上下文登记,因为这个handler是上下文注册之后才能执行的
		 AbstractRuntime.getRuntime(ctx.channel()).removeChannelContext(ctx.channel());
		super.close(ctx, promise);
	}
}
